package com.ycy;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CountDownLatch;

public class ZookeeperClientDemo1 implements Watcher {


  ZookeeperClientDemo1 zooKeeper;

  CountDownLatch countDownLatch = new CountDownLatch(1);

  ZooKeeper zk;

  public ZookeeperClientDemo1() {
    try {
      String connectString = "10.211.55.3:2182,10.211.55.3:2183,10.211.55.3:2184";
      connectString = "192.168.1.9";
      this.zk =
              new ZooKeeper(connectString
                      , 10000
                      , this);
//        this.countDownLatch.countDown();
      countDownLatch.await();
    } catch (IOException | InterruptedException e) {
      e.printStackTrace();
    }
  }

  @Override
  public void process(WatchedEvent event) {
    String x = "事件:" + event;
    System.out.println(new Date(System.currentTimeMillis()) + ":" + Thread.currentThread().getName() + ":" + x);

    Event.KeeperState state = event.getState();
    Event.EventType type = event.getType();
    if (state == Watcher.Event.KeeperState.SyncConnected && Event.EventType.None == type) {
      this.countDownLatch.countDown();
    }
  }

  @Before
  public void before() {
    this.zooKeeper = new ZookeeperClientDemo1();
  }

  /**
   * 创建一个节点
   */
  @Test
  public void test() {
    try {
      this.zooKeeper.createNode("/ycy2");
    } catch (KeeperException e) {
      e.printStackTrace();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

  }

  /**
   * 删除
   */
  @Test
  public void test1() {
    try {
      this.zooKeeper.deleteNode("/ycy1");
    } catch (KeeperException e) {
      e.printStackTrace();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

  @Test
  public void test2() {
    //获取孩子节点
    this.zooKeeper.getChildrenNode("/ycy2");
  }

  @Test
  public void test3() {
    this.zooKeeper.getDate("/ycy2");

    this.zooKeeper.setData("/ycy2", "hello");
    while (true) {
      try {
        String data = this.zooKeeper.getDate("/ycy2");
        System.out.println(data);

        Thread.sleep(2000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }

//    this.zooKeeper.release();
  }

  @Test
  public void test4() {
    // 可以监听节点的创建 和 删除
    boolean exits = this.zooKeeper.exits("/ycy2/meimei3", true);
    try {
      if (exits)
        this.zooKeeper.deleteNode("/ycy2/meimei3");
      else
        this.zooKeeper.createNode("/ycy2/meimei3");
    } catch (KeeperException e) {
      e.printStackTrace();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

  //获取当前节点的孩子节点
  @Test
  public void testGetChild() {
    List<String> childrenNode = getChildrenNode("/ycy/lock");
    for (String s : childrenNode) {
      System.out.println(s);
    }
  }

  //测试 getChildNode 的事件触发条件
  @Test
  public void test5() {
    try {

      boolean exits = this.zooKeeper.exits("/ycy2/meimei", false);
      if (exits) {
        this.zooKeeper.deleteNode("/ycy2/meimei");
      }

      boolean exits1 = this.zooKeeper.exits("/ycy2/meimei2", false);
      if (exits1) {
        this.zooKeeper.deleteNode("/ycy2/meimei2");
      }

      // 创建一个孩子节点
      this.zooKeeper.createNode("/ycy2/meimei");

      //读取孩子节点 并监听
      List<String> childrenNode = this.zooKeeper.getChildrenNode("/ycy2");

      //修改孩子节点的值 是否能触发事件 答案：不能
//      this.zooKeeper.setData("/ycy2/meimei","helloword");

      //删除子节点，是否能触发监听事件 答案：能
//      this.zooKeeper.deleteNode("/ycy2/meimei");

    } catch (KeeperException e) {
      e.printStackTrace();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

  @Test
  public void test6() {
    try {
      boolean exits = this.zooKeeper.exits("/ycy2/meimei/meimeimei", false);
      if (exits) {
        this.zooKeeper.deleteNode("/ycy2/meimei/meimeimei");
      }

      boolean exits2 = this.zooKeeper.exits("/ycy2/meimei", false);
      if (exits2) {
        this.zooKeeper.deleteNode("/ycy2/meimei");
      }

      //读取孩子节点 并监听
      List<String> childrenNode1 = this.zooKeeper.getChildrenNode("/ycy2");
      this.zooKeeper.createNode("/ycy2/meimei");

      //读取孩子节点 并监听
      List<String> childrenNode2 = this.zooKeeper.getChildrenNode("/ycy2");
      // 触发不了 /ycy2 的监听
      this.zooKeeper.createNode("/ycy2/meimei/meimeimei");

    } catch (KeeperException e) {
      e.printStackTrace();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }


  /**
   * 创建一个节点
   */
  public void createNode(String node) throws KeeperException, InterruptedException {
    String s = this.zk.create(node, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
    System.out.println(s);
  }

  /**
   * 删除一个节点
   */
  public void deleteNode(String node) throws KeeperException, InterruptedException {
    this.zk.delete(node, -1);
  }

  public void setData(String path, String data) {
    try {
      this.zk.setData(path, data.getBytes(), -1);
    } catch (KeeperException e) {
      e.printStackTrace();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }


  public String getDate(String path) {
    try {
      byte[] data = this.zk.getData(path, true, null);
      return new String(data);
    } catch (KeeperException e) {
      e.printStackTrace();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    return null;
  }

  public List<String> getChildrenNode(String path) {
    try {
      List<String> children = this.zk.getChildren(path, true, null);
      for (String child : children) {
        System.out.println(child);
      }
      return children;
    } catch (KeeperException | InterruptedException e) {
      e.printStackTrace();
    }
    return null;
  }

  public boolean exits(String path) {
    return exits(path, true);
  }

  public boolean exits(String path, boolean watcher) {
    try {
      Stat exists = this.zk.exists(path, watcher);
      return !(exists == null);
    } catch (KeeperException e) {
      e.printStackTrace();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    return false;
  }

  public void release() {
    if (this.zk != null) {
      try {
        this.zk.close();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }


}
